<?php
/***
 * Candy框架 框架Hook钩子类
 * 
 * $Author: 刘森 (fingerboy@qq.com) $
 * $Date: 2019-08-03 08:31:01 $   
 */

//语法严格模式开启
declare(strict_types=1);

namespace Candy\Core;

defined('CANDY') OR die('You Are A Bad Guy. o_O???');

final Class Hook {
	
	/**
	 * 获取hook内容
	 *
	 * @param	$hookfile	hook路径
	 * @param	$force	强制关闭验证
	 */
	private static function processHook(string $hookfile): string
	{
		$s = '';
		$hooks = self::getEnableHooks();
		$hooknames = array_keys($hooks);
		
		foreach($hooknames as $v){
			$path = PLUGPATH . $v;
			if(!is_file($path.'/Hook/'.$hookfile))
				continue;
			
			if(empty($hooks[$v]))
				continue;
			
			$s2 = stripWhitespace(file_get_contents($path.'/Hook/'.$hookfile));			
			$s2 = preg_replace('#^<\?php\s*exit;\?>\s{0,2}#i', '', $s2);
			if(substr($s2, 0, 5) == '<?php' && substr($s2, -2, 2) == '?>'){
				$s2 = substr($s2, 5, -2);		
			}
			$s .= $s2;
		}
		return $s;
	}
	
	/**
	 * 获取使用的hook
	 */
	public static function getEnableHooks(bool $force = true): array
	{
		$force === true ? $hooks = self::getHooks() : $hooks = [];
		
		static $enable_hooks = [];
		if(!empty($enable_hooks) && !$force) return $enable_hooks;
		foreach($hooks as $k=>$hook){
			if((isset($hook['installed']) && $hook['installed'] == 1 && isset($hook['enable']) && $hook['enable'] == 1) || $k == C('RAPPNAME') || $k == $hook['pertain']){
				$enable_hooks[$k] = $hook;
			}
		}
		return $enable_hooks;
	}
	
	/**
	 * 获取hook
	 */
	public static function getHooks(): array
	{
		static $hooks = [];
		$path = PLUGPATH;
		if(!is_dir($path)) return [];
		$hook_path = INCPATH.'Plug.inc.php';
		$setting = is_file($hook_path) ? include($hook_path) : [];
		$hook_list = $setting['PLUG_LIST'];
		$arr = dirs($path);
		foreach($arr as $v){
			$conffile = $path.$v.'/conf.php';
			$conf = is_file($conffile) ? (array)include($conffile) : [];
			if(!empty($conf)){
				!isset($conf['enable']) && $conf['enable'] = isset($hook_list[$v]['enable']) ? $hook_list[$v]['enable'] : 0;
				!isset($conf['installed']) && $conf['installed'] = isset($hook_list[$v]['installed']) ? $hook_list[$v]['installed'] : 0;
				!isset($conf['plugid']) && $conf['plugid'] = isset($hook_list[$v]['plugid']) ? $hook_list[$v]['plugid'] : 0;
				!isset($conf['rank']) && $conf['rank'] = isset($hook_list[$v]['rank']) ? $hook_list[$v]['rank'] : 100; // 按照正序排序
				!isset($conf['pertain']) && $conf['pertain'] = '';
				$hooks[$v] = $conf;
			}
		}
		
		//当前项目的同名插件直接添加
		$hooks[C('RAPPNAME')] = ['rank'=>100];
		
		$hooks = \Candy\Extend\Arr::arraySort($hooks, 'rank');
		return $hooks;
	}
	
	/**
	 *检查Hook回调接口
	 * 
	 * @param	$matchs	hook路径数组
	 */
	public static function processHookCallback(array $matchs): string
	{
		$s = $matchs[1];
		return self::processHook($s);
	}
}
